#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "car.h"
#include "tunnel.h"

#define MAX_OPERATIONS 10
int DEBUG_FLAG = 0;

// 全局变量存储红绿灯进程PID
static pid_t traffic_light_pid = -1;

// 信号处理函数
void handle_signal(int sig) {
    if (traffic_light_pid > 0) {
        kill(traffic_light_pid, SIGTERM);
    }
    exit(0);
}

int main(int argc, char **argv) {
    int total_number_of_cars, max_number_of_car_in_tunnel, tunnel_travel_time, total_number_of_mailboxes, memory_segment_size;
    FILE *fin = fopen(argv[1], "r");
    if (fin == NULL) {
        printf("No such file!\n");
        return 0;
    }
    fscanf(fin, "%d %d %d %d %d", &total_number_of_cars, &max_number_of_car_in_tunnel, &tunnel_travel_time, &total_number_of_mailboxes, &memory_segment_size);
    
    Tunnel *T = create_tunnel(max_number_of_car_in_tunnel, total_number_of_mailboxes, memory_segment_size, tunnel_travel_time);
    init_traffic_light(T);
    // 启动红绿灯控制进程
    signal(SIGTERM, handle_signal);
    signal(SIGINT, handle_signal); //注册信号处理函数
    traffic_light_pid = fork();
    if (traffic_light_pid == 0) {
        // 子进程：红绿灯控制器
        traffic_light_controller(T);
        exit(0);
    }
    Car **cars = (Car**)malloc(total_number_of_cars * sizeof(Car*));
    char line[100],temp[20];
    int i;
    fgets(line, sizeof(line), fin); // 跳过换行符
    for (i = 0; i < total_number_of_cars; i++) {
        cars[i] = create_car(i, T);
        fgets(line, sizeof(line), fin); // 跳过空行
        fgets(line, sizeof(line), fin); // car_no_x
        cars[i]->direction = 0;
        sscanf(line, "%s %d", temp, &cars[i]->direction);
        
        #ifdef DEBUG
        fprintf(stderr, "Car %d direction: %d\n", i, cars[i]->direction); 
        #endif
        
        int op_count = 0;
        CarOp *operations = NULL;
        while (1) {
            fgets(line, sizeof(line), fin);
            line[strcspn(line, "\r")] = '\0';
            line[strcspn(line, "\n")] = '\0';
            //fprintf(stderr, "Line: %s\n", line);
            if (strcmp(line, "end.") == 0 || op_count >= MAX_OPERATIONS) {
                if(DEBUG_FLAG){
                    fprintf(stderr, "Car %d has %d operations.\n", i, op_count); 
                }
                break;
            }
            operations = (CarOp*)realloc(operations, (op_count + 1) * sizeof(CarOp));
            sscanf(line, "%s %s %d %d", operations[op_count].op, operations[op_count].content, &operations[op_count].duration, &operations[op_count].mid);
            
            #ifdef DEBUG
            fprintf(stderr, "Car %d operation %d: %s %s %d %d\n", i, op_count, operations[op_count].op, operations[op_count].content, operations[op_count].duration, operations[op_count].mid); 
            #endif
            
            op_count++;
        }
        cars[i]->operation = operations;
        cars[i]->op_count = op_count;
    }
    fclose(fin);

    pid_t mypid;
    for (i = 0; i < total_number_of_cars; i++) {
        mypid = fork();
        if (mypid == 0) {
            exec_car(cars[i]);
            printf("[Car %d]: The car finished its operation.\n", i);
            break;
        } else {
            usleep(50000);
        }
    }
    if (mypid != 0) {
        int childfinish = 0;
        while (childfinish < total_number_of_cars) {
            if (wait(NULL) != -1) {
                childfinish++;
            }
        }
        printf("\nAll of the cars are leaving the tunnel.\n");
        print_memory(T);
        // 终止红绿灯控制进程
        if (traffic_light_pid > 0) {
            kill(traffic_light_pid, SIGTERM);
            waitpid(traffic_light_pid, NULL, 0);
        }
        destroy_tunnel(T);
        free(cars);
    }
    return 0;
}
